﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using Sustainalytics.DataLayer;

namespace Sustainalytics.PregenerateScreeningReports.Service.Tests
{
    using Sustainalytics.Entities.ConnectionStrings;

    [TestClass]
    public class OrchestratorTests
    {
        [TestMethod]
        public void SpawnSubprocessTest()
        {
            Process.GetProcessesByName("notepad").ToList().ForEach(x => x.Kill());
            var count = 8;
            var total = 64;
            var jobs = new List<string>();
            for (var i = 0; i < total; i++)
                jobs.Add(" ");

            var t = Task.Run(() =>
            {
                var obj = new Orchestrator();
                obj.SpawnSubprocess(jobs, count, "notepad.exe", 0);
            });

            // confirm that we have spawned 8 processes
            Thread.Sleep(1000);
            var processes = Process.GetProcessesByName("notepad");
            Assert.AreEqual(count, processes.Count());

            var killed = 0;
            do
            {// confirm that killing 1 process  makes it replaced with another, always having 8  running
                processes.First().Kill();
                killed++;
                Thread.Sleep(300);
                processes = Process.GetProcessesByName("notepad");
                var expected = count;
                if (killed > total - count) // except the last batch of 8
                    expected = total - killed;
                Assert.AreEqual(expected, processes.Count());
            }
            while (killed < total);

            t.Wait();
            Assert.AreEqual(0, Process.GetProcessesByName("notepad").Count());
        }

        [TestMethod]
        public void CommandLineTest()
        {
            var count = 50;
            var limit = 1024;
            var list = new List<Guid>();
            for (int i = 0; i < count; i++)
                list.Add(Guid.NewGuid());

            var obj = new Orchestrator();
            var result = obj.CommandLine("xxxxxxxxxxxxxxxxxxxxxx", list, limit);
            result.ToList().ForEach(s => Assert.IsTrue(s.Length < limit));

            Assert.AreEqual(2, result.Count());
        }

        [TestMethod]
        public void UpdateSessionTest()
        {
            var session = new ScreeningToolReportDistributionSession { Id = Guid.NewGuid(), ConnectionStrings = new Dictionary<ConnectionStringType, string>() };

            session.Date = DateTime.Now;
            session.MainMachine = "test";
            session.Machines = new List<ScreeningToolReportDistributionSession.MachineData>() { new ScreeningToolReportDistributionSession.MachineData { MachineId = "test" } };
            session.ConnectionStrings[ConnectionStringType.ClientDW] = "one";
            session.ConnectionStrings[ConnectionStringType.ClientPlatform] = "two";

            var sessionColl = MongoDatabaseFactory.GetDatabase("mongodb://localhost:27017/UnitTests")
                                                  .GetCollection<ScreeningToolReportDistributionSession>();

            sessionColl.InsertOne(session);

            session.Completed = true;

            var obj = new Orchestrator("mongodb://localhost:27017/UnitTests", "mongodb://localhost:27017/UnitTests", "test", string.Empty, string.Empty, string.Empty, 1, 0);
            obj.UpdateSession(session);

            Assert.IsTrue(true);
        }
    }
}
